/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.xuexiang.xui_lib.component.textview.marqueen;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Text;
import ohos.agp.text.RichText;
import ohos.agp.text.RichTextBuilder;
import ohos.agp.text.TextForm;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

import java.util.ArrayList;

/**
 * 日志打印显示控件
 *
 * @since 2021-04-10
 */
public class LogText extends Text {
    private static final String TAG = "LogText";
    private static final int TEXT_SIZE = 40;
    private final RichTextBuilder builder = new RichTextBuilder();
    private ArrayList<TextType> history = new ArrayList<>();

    /**
     * 构造方法
     *
     * @param context 上下文
     */
    public LogText(Context context) {
        this(context, null);
    }

    /**
     * 构造方法
     *
     * @param context 上下文
     * @param attrs UI属性对象
     */
    public LogText(Context context, AttrSet attrs) {
        this(context, attrs, "");
    }

    /**
     * 构造方法
     *
     * @param context 上下文
     * @param attrs UI属性对象
     * @param styleName 设置style名称
     */
    public LogText(Context context, AttrSet attrs, String styleName) {
        super(context, attrs, styleName);
        this.mContext = context;
    }

    /**
     * 添加普通日志
     *
     * @param logContent 日志内容
     */
    public void logNormal(String logContent) {
        addLog(logContent, LogType.NORMAL);
    }

    /**
     * 添加成功日志
     *
     * @param logContent 日志内容
     */
    public void logSuccess(String logContent) {
        addLog(logContent, LogType.SUCCESS);
    }

    /**
     * 添加错误日志
     *
     * @param logContent 日志内容
     */
    public void logError(String logContent) {
        addLog(logContent, LogType.ERROR);
    }

    /**
     * 添加警告日志
     *
     * @param logContent 日志内容
     */
    public void logWarning(String logContent) {
        addLog(logContent, LogType.WARNING);
    }

    /**
     * 用于设置builder的内容
     *
     * @since 2021-04-10
     */
    static class TextType {
        private String content;
        private TextForm textForm;
    }

    /**
     * 添加日志
     *
     * @param logContent 日志内容
     * @param logType 日志类型
     */
    public void addLog(String logContent, LogType logType) {
        TextType textType = new TextType();
        String tail = "                                                                                    ";
        switch (logType) {
            case NORMAL:
                textType.textForm = new TextForm().setTextColor(Color.GRAY.getValue()).setTextSize(TEXT_SIZE);
                textType.content = logContent + tail;
                break;
            case SUCCESS:
                textType.textForm = new TextForm().setTextColor(Color.GREEN.getValue()).setTextSize(TEXT_SIZE);
                textType.content = logContent + tail;
                break;
            case ERROR:
                textType.textForm = new TextForm().setTextColor(Color.RED.getValue()).setTextSize(TEXT_SIZE);
                textType.content = logContent + tail;
                break;
            case WARNING:
                textType.textForm = new TextForm().setTextColor(Color.getIntColor("#EEB422")).setTextSize(TEXT_SIZE);
                textType.content = logContent + tail;
                break;
            default:
                break;
        }
        history.add(textType);
        for (TextType textType1 : history) {
            builder.mergeForm(textType1.textForm);
            builder.addText(textType1.content);
        }
        builder.revertForm();
        appendLogInMainThread(builder);
    }

    private void appendLogInMainThread(final RichTextBuilder richTextBuilder) {
        EventRunner eventRunner = EventRunner.create(true);
        if (eventRunner.getThreadId() == EventRunner.getMainEventRunner().getThreadId()) {
            appendLog(richTextBuilder);
        } else {
            runMainThread(() -> appendLog(richTextBuilder));
        }
    }

    /**
     * 设置RichTextBuilder内容
     *
     * @param richTextBuilder 设置的builder对象
     */
    private void appendLog(RichTextBuilder richTextBuilder) {
        RichText richText = richTextBuilder.build();
        setRichText(richText);
        scrollToEnd();
    }

    /**
     * 切换任务到主线程执行
     *
     * @param runnable 执行的runnable
     */
    public static void runMainThread(Runnable runnable) {
        EventRunner eventRunner = EventRunner.getMainEventRunner();
        EventHandler eventHandler = new EventHandler(eventRunner);
        eventHandler.postSyncTask(runnable);
    }

    /**
     * 滑动至最后一行
     */
    private void scrollToEnd() {
        int offset = getTextRealHeight();
        if (offset > getHeight()) {
            scrollTo(0, offset - getHeight());
        }
    }

    /**
     * 获取当前TextView文字的真实高度
     *
     * @return 返回高度值
     */
    private int getTextRealHeight() {
        return getMaxTextHeight();
    }

    /**
     * 清除日志
     */
    public void clearLog() {
        history.clear();
        builder.addText("");
        builder.revertForm();
        EventRunner eventRunner = EventRunner.create(true);
        if (eventRunner.getThreadId() == EventRunner.getMainEventRunner().getThreadId()) {
            setRichText(builder.build());
            scrollTo(0, 0);
        } else {
            runMainThread(() -> {
                setRichText(builder.build());
                scrollTo(0, 0);
            });
        }
    }

    /**
     * 日志类型
     *
     * @since 2021-04-10
     */
    public enum LogType {
        /**
         * 普通日志
         */
        NORMAL,
        /**
         * 成功日志
         */
        SUCCESS,
        /**
         * 出错日志
         */
        ERROR,
        /**
         * 警告日志
         */
        WARNING
    }
}
